using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Db4objects.Db4o;
using Db4objects.Db4o.Query;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.BO.Loaders;
using Habanero.DB4O;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic
{
    [TestFixture]
    [Ignore("This doesn't apply to FireStarter Modeller")]
    public class TestDB4OServer
    {
        #region Setup/Teardown

        [TestFixtureSetUp]
        public virtual void TestFixtureSetup()
        {
            TestUtils.SetupFixture();
        }

        [SetUp]
        public virtual void SetupTest()
        {
            IObjectContainer client = Db4oFactory.OpenClient("localhost", 5214, "bob", "bob");
            DB4ORegistry.DB = client;
            BORegistry.DataAccessor = new DataAccessorDB4O(DB4ORegistry.DB);
        }

        [TearDown]
        public virtual void TearDownTest()
        {
        }

        #endregion

        [Test]
        public void Test_CreateSolution_ShouldCreateStandardTypes()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = new DMSolution(TestUtilsShared.GetRandomString());
            DMAssembly dmAssembly = new DMAssembly(TestUtilsShared.GetRandomString());
            dmSolution.DefaultAssembly = dmAssembly;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            dmSolution.Save();
            //---------------Test Result -----------------------
            DMSolution solution = Broker.GetBusinessObject<DMSolution>("SolutionName='" + dmSolution.SolutionName + "'");
            Assert.IsNotNull(solution);
        }

        [Test]
        public void Test_Save_DummyBO()
        {
            //---------------Set up test pack-------------------
            IObjectContainer client = Db4oFactory.OpenClient("localhost", 5214, "bob", "bob");

            DB4ORegistry.DB = client;
            BORegistry.DataAccessor = new DataAccessorDB4O(DB4ORegistry.DB);

            DummyBO.LoadClassDefsNoUIDef();
            DummyBO dmSolution = new DummyBO();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            dmSolution.Save();
            //---------------Test Result -----------------------
            DummyBO dummyBO = Broker.GetBusinessObject<DummyBO>(dmSolution.ID);
            Assert.IsNotNull(dummyBO);
        }
        [Test]
        public void Test_Save_DummyBO_Retrieve()
        {
            //---------------Set up test pack-------------------
            IObjectContainer client = Db4oFactory.OpenClient("localhost", 5214, "bob", "bob");

            DB4ORegistry.DB = client;
            BORegistry.DataAccessor = new DataAccessorDB4O(DB4ORegistry.DB);

            DummyBO.LoadClassDefsNoUIDef();
            DummyBO dmSolution = new DummyBO();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            dmSolution.Save();
            //---------------Test Result -----------------------
            IList<BusinessObjectDTO> query = client.Query<BusinessObjectDTO>(Predicate);
            Assert.AreEqual(1,query.Count);
            client.Close();
        }

        private bool Predicate(BusinessObjectDTO dto)
        {
            bool b = dto.ClassDefName == "DummyBO";
            return b;
        }

        [Test]
        public void Test_Save_DummyBO_Store()
        {
            //---------------Set up test pack-------------------
            IObjectContainer client = Db4oFactory.OpenClient("localhost", 5214, "bob", "bob");

            DB4ORegistry.DB = client;
            BORegistry.DataAccessor = new DataAccessorDB4O(DB4ORegistry.DB);

            DummyBO.LoadClassDefsNoUIDef();
            DummyBO dmSolution = new DummyBO();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            client.Store(dmSolution);
            //---------------Test Result -----------------------
            IList<DummyBO> query = client.Query<DummyBO>();
            Assert.AreEqual(1,query.Count);
        }
        
        [Test]
        public void Test_Save_CreateServer()
        {
            //---------------Set up test pack-------------------
            IObjectServer server = Db4oFactory.OpenServer("TestDB4o.db4o", 5621);
            server.GrantAccess("bob","bob");

            IObjectContainer client = Db4oFactory.OpenClient("localhost", 5621, "bob", "bob");
            DB4ORegistry.DB = client;

            BORegistry.DataAccessor = new DataAccessorDB4O(DB4ORegistry.DB);

            DummyBO.LoadClassDefsNoUIDef();
            DummyBO dmSolution = new DummyBO();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            dmSolution.Save();
            //---------------Test Result -----------------------
            DummyBO dummyBO = Broker.GetBusinessObject<DummyBO>(dmSolution.ID);
            Assert.IsNotNull(dummyBO);
        } 
        
        [Test]
        public void Test_Save_FileBased()
        {
            //---------------Set up test pack-------------------
            IObjectContainer client = Db4oFactory.OpenFile("TestDb4oFile.db4o");
            DB4ORegistry.DB = client;

            BORegistry.DataAccessor = new DataAccessorDB4O(DB4ORegistry.DB);

            DummyBO.LoadClassDefsNoUIDef();
            DummyBO dmSolution = new DummyBO();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            dmSolution.Save();
            //---------------Test Result -----------------------
            DummyBO dummyBO = Broker.GetBusinessObject<DummyBO>(dmSolution.ID);
            Assert.IsNotNull(dummyBO);
        }
        [Test]
        public void Test_Save_Memory()
        {
            //---------------Set up test pack-------------------
            IObjectContainer client = Db4oFactory.OpenFile("TestDb4oFile.db4o");
            DB4ORegistry.DB = client;

            DummyBO.LoadClassDefsNoUIDef();
            DummyBO dmSolution = new DummyBO();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            dmSolution.Save();
            //---------------Test Result -----------------------
            DummyBO dummyBO = Broker.GetBusinessObject<DummyBO>(dmSolution.ID);
            Assert.IsNotNull(dummyBO);
        }
    }

    internal class DummyBO : BusinessObject
    {
        public static ClassDef LoadClassDefsNoUIDef()
        {
            XmlClassLoader itsLoader = new XmlClassLoader();
            ClassDef itsClassDef =
                itsLoader.LoadClass(
                    @"
				<class name=""DummyBO"" assembly=""FireStarterModeller.Test.Logic"">
					<property  name=""MyBoID""  type=""Guid"" />
					<primaryKey>
						<prop name=""MyBoID"" />
					</primaryKey>
				</class>
			");
            ClassDef.ClassDefs.Add(itsClassDef);
            return itsClassDef;
        }
    }
}
